'use strict';
const Service = require('egg').Service;
const WebSocketClient = require('websocket').client;
let timeoutObj = null;
class websocketClient extends Service {
  async start(query) {
    const ctx = this.ctx;
    const app = this.app;
    const url = query && query.url ? query.url : this.app.config.sysProperty.clientUrl;
    console.log('url=========', url);
    const client = new WebSocketClient(url + '/peer_id=' + this.app.config.sysProperty.subServerId + '&type=sub');
    client.connect(url + '?peer_id=' + this.app.config.sysProperty.subServerId + '&type=sub');

    client.on('connect', connection => {
      console.log('连接成功');
      // 缓存连接
      app.clientInstance = connection;
      // app.wsClients.set(peer_id, connection);
      // 保持心跳
      this.heartCheck();
      // 接收公网服务传送的message
      connection.on('message', e => {
        // 解析
        let message = {};
        try {
          message = JSON.parse(e.utf8Data);
        } catch (e) {
          console.log('receive message error:', e);
        }
        // hanyf 20210110 ctx.logger.info("收到公网信息 =>", message);
        if (message.event == 'pong') {
          console.log('收到心跳响应：pong');
          return;
        }

        // 响应心跳
        if (message.event == 'ping') {
          connection.send(
            JSON.stringify({
              event: 'pong',
            })
          );
          return;
        }
        // 业务逻辑处理
        ctx.helper.handleWebsocketClient(message, connection);
      });

      connection.on('error', error => {
        ctx.logger.info('子服务连接公网服务出现 => Connection Error: ' + error.toString());
      });

      // 中途server端挂掉后，此方法会触发
      connection.on('close', () => {
        this.start(query);
        ctx.logger.info('连接中断 => connection closed');
      });
    });
    // 连接失败，会触发此方法
    client.on('connectFailed', error => {
      // 连接出错后，五秒重连一次
      setTimeout(() => {
        this.start(query);
      }, 7000);
      console.log('连接出错: ', error.toString());
      ctx.logger.info('连接出错: ', error.toString());
    });
  }

  heartCheck() {
    const timeout = 12 * 1000;
    const app = this.app;
    timeoutObj && clearTimeout(timeoutObj);
    timeoutObj = setTimeout(() => {
      if (this.app.clientInstance) {
        this.app.clientInstance.send(
          JSON.stringify({
            event: 'ping',
          })
        );
        this.heartCheck();
      }
    }, timeout);
  }
}
module.exports = websocketClient;
